<template>
  <div class="home">
    <div class="header">
      <div class="header__title">
        {{ config.catalogueName || "未命名模板" }}
      </div>
      <div class="header__btns">
        <el-button @click="btnLeave">返回</el-button>
        <el-button @click="preview">预览</el-button>
        <el-button @click="clearWidgetConfig">清空</el-button>
        <el-button type="primary" @click="saveConfig">保存</el-button>
      </div>
    </div>
    <el-container class="container-main">
      <el-aside class="main-right">
        <div class="pd-10">
          <el-header class="header-title">
            <span>基础配置</span>
            <!-- <el-button type="text" icon="el-icon-document" @click="saveConfig"
              >保存</el-button
            > -->
          </el-header>
          <el-form size="mini" label-position="top">
            <el-form-item label="模板名称 (不超过20字)">
              <el-input
                v-model="config.catalogueName"
                placeholder="输入模板内容"
                :maxlength="20"
              ></el-input>
            </el-form-item>
            <el-form-item label="备注 (不超过60字)">
              <el-input
                v-model="config.remark"
                placeholder="输入备注内容"
                type="textarea"
                :rows="3"
                :maxlength="60"
              >
              </el-input>
            </el-form-item>
          </el-form>
        </div>
        <div class="divider"></div>
        <div class="pd-10">
          <el-header class="header-title">基础组件</el-header>
          <draggable
            :list="CommonUserComponents"
            :move="() => true"
            class="draggable-container"
            v-bind="{
              group: {
                name: 'people', // 同分组可以互相拖拽
                pull: 'clone', // 拖拽变为复制
                put: false, // 是否允许拖入当前组
              },
              sort: false,
              ghostClass: 'ghostClass',
            }"
          >
            <div
              v-for="(item, index) in CommonUserComponents"
              :key="index"
              class="c-tag"
            >
            <svg-icon
              :icon-class="'c-'+item.type"
              class="c-tag__icon"
            ></svg-icon>
              <div class="c-tag__name">{{ item.name }}</div>
            </div>
            <!-- <el-tag
              v-for="(item, index) in CommonUserComponents"
              :key="index"
              effect="dark"
            >
              <i :class="item.icon"></i>
              {{ item.name }}
            </el-tag> -->
          </draggable>
        </div>
      </el-aside>
      <el-container>
        <!--   菜单栏       -->
        <!-- <el-header class="main-bottom header-padding">
          <el-tag
            effect="plain"
            type="danger"
            class="header-tags"
            @click="clearWidgetConfig"
          >
            <i class="el-icon-delete"></i><span>清空</span>
          </el-tag>
          <el-tag
            type=""
            effect="plain"
            class="header-tags"
            @click="saveWidgetConfig"
            ><i class="el-icon-document"></i><span>生成JSON</span>
          </el-tag>
          <el-tag
            effect="plain"
            type=""
            class="header-tags"
            @click="setFormJson"
            ><i class="el-icon-connection"></i><span>导入JSON</span>
          </el-tag>
        </el-header> -->
        <el-main class="box-padding">
          <!--   渲染区     -->
          <!-- <div class="widget-form-container"> -->
          <WidgetForm
            ref="configFormData"
            :select.sync="widgetFormSelect"
            :config-form-data="configFormData"
          />
          <!-- </div> -->
        </el-main>
      </el-container>
      <el-aside class="main-left">
        <div class="header-title">
          <span> 组件配置</span>
          <!-- <el-button
            type="text"
            icon="el-icon-delete"
            @click="clearWidgetConfig"
            style="color:#f56c6c"
            >清空</el-button
          > -->
        </div>
        <WidgetConfig :eleItem.sync="widgetFormSelect" />
        <!-- <el-tabs v-model="activeName">
          <el-tab-pane label="组件设置" name="first">
            <WidgetConfig :eleItem.sync="widgetFormSelect" />
          </el-tab-pane>
          <el-tab-pane label="表单属性" name="second">
            <FormConfig :formdata="configFormData.config" />
          </el-tab-pane>
        </el-tabs> -->
      </el-aside>
    </el-container>
    <!-- 生成json框 -->
    <el-dialog :title="dialogTitle" :visible.sync="jsonDialog" top="5vh">
      <div v-if="!jsonTextareaReadonly">
        JSON格式如下，直接复制生成的json覆盖此处代码点击确定即可
      </div>
      <div style="max-height: 400px; overflow-y: scroll">
        <el-input
          type="textarea"
          autosize
          :readonly="jsonTextareaReadonly"
          v-model="jsonmsg"
        >
        </el-input>
      </div>
      <span slot="footer" class="dialog-footer" v-if="!jsonTextareaReadonly">
        <el-button @click="jsonDialog = false">取 消</el-button>
        <el-button type="primary" @click="setJsonBtn">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 预览弹出框 -->
    <el-dialog
      title="表单预览"
      :visible.sync="dialogVisible"
      width="70%"
      top="5vh"
    >
      <form-generator :catalogue="previewData" :isEdit="true"></form-generator>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import draggable from "vuedraggable";
import WidgetForm from "./components/WidgetForm";
import WidgetConfig from "./components/WidgetConfig";
import { CommonUserComponents, tag2component, dateMap } from "./config.js";
import FormGenerator from "@/components/CatalogueForm/components/FormGenerator";
import { add, detail, edit } from "@/api/system-config/catalogue";
import leave from "@/views/_mixins/leave";
export default {
  name: "form-generate",
  components: {
    draggable,
    WidgetForm,
    WidgetConfig,
    FormGenerator,
  },
  mixins: [leave],
  data() {
    return {
      config: {
        catalogueName: "",
        remark: "",
      },
      CommonUserComponents,
      // 渲染区表单config
      configFormData: {
        // 拖拽区接收到的组件
        list: [],
        // 拖拽区el-form属性
        config: {
          labelWidth: 100,
          labelPosition: "right",
          size: "small",
        },
      },
      // 选中的元素
      widgetFormSelect: {
        key: null,
        options: {
          placeholder: "",
        },
      },
      activeName: "first",
      dialogTitle: "",
      // 生成json弹框
      jsonDialog: false,
      // 弹出文本域是否可编辑,默认不可编辑
      jsonTextareaReadonly: true,
      // 生成的json语句
      jsonmsg: "",
      dialogVisible: false, // demo dialog
      previewData: null,
    };
  },
  created() {
    if (this.$route.query.id) {
      this.$id = this.$route.query.id;
      this.initData();
    }
  },
  methods: {
    initData() {
      detail(this.$id).then(({ args, catalogueName, remark }) => {
        this.config = {
          catalogueName,
          remark,
        };
        const list = [];
        for (const item of args) {
          let raw = {
            argId:item.argId,
            name: item.argTitle,
            tag: item.argType,
            key: item.argId,
            type: tag2component[item.argType],
            options: {
              required: !!item.mustFill,
            },
          };
          let options;
          switch (item.argType) {
            case 1:
            case 2:
              options = item.textDetail;
              raw.options.placeholder = options.argPlaceholder;
              raw.options.maxlength = options.maxLength;
              raw.options.minlength = options.minLength;
              break;
            case 3:
            case 4:
            case 5:
            case 6:
              options = item.checkDetail;
              function format(arr) {
                const result = [];
                for (const item of arr) {
                  if (item.subOption) {
                    result.push({
                      label: item.optionName,
                      children: format(item.subOption),
                    });
                  } else {
                    result.push({
                      label: item.optionName,
                      children:[]
                    });
                  }
                }
                return result;
              }
              raw.options.valueData = format(options);
              if (item.argType == 6) {
                raw.options.defaultValue = []; //多选框值数组
              }
              break;
            case 7:
              options = item.dateDetail;
              for (const key in dateMap) {
                if (Object.hasOwnProperty.call(dateMap, key)) {
                  const { dateLength, dateType } = dateMap[key];
                  if (
                    options.dateLength === dateLength &&
                    options.dateType === dateType
                  ) {
                    raw.options.type = key;
                  }
                }
              }

              break;
            case 8:
              options = item.fileDetail;
              raw.options.accept = options.psuffix.split(",");
              break;
            case 9:
              options = item.fileDetail;
              raw.options.accept = {};
              raw.options.accept.photo = options.psuffix.split(",");
              raw.options.accept.video = options.vsuffix.split(",");
              raw.options.accept.audio = options.asuffix.split(",");
              raw.options.accept.doc = options.dsuffix.split(",");
              break;
            default:
              break;
          }
          list.push(raw);
        }
        this.configFormData.list = list;
        list.length && (this.widgetFormSelect = this.configFormData.list[0]);
      });
    },
    clearWidgetConfig() {
      // 重置formConfig
      this.$confirm(`清空后内容无法找回，是否清空？`, "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        cancelButtonClass: 'cancel-msgbtn', confirmButtonClass: 'confirm-msgbtn', type: 'warning',
      }).then(() => {
        this.configFormData = {
          list: [],
          config: {
            labelWidth: 100,
            labelPosition: "right",
            size: "small",
          },
        };
        // 重置选中的组件
        this.widgetFormSelect = {
          key: null,
          options: {
            placeholder: null,
          },
        };
      });
    },
    // 保存json
    saveWidgetConfig() {
      this.dialogTitle = "生成json";
      this.jsonTextareaReadonly = true;
      this.jsonDialog = true;
      this.jsonmsg = JSON.stringify(this.configFormData, null, 1);
    },
    setFormJson() {
      this.dialogTitle = "导入JSON";
      this.jsonTextareaReadonly = false;
      this.jsonDialog = true;
      this.jsonmsg = JSON.stringify(
        {
          list: [],
          config: {
            labelWidth: 100,
            labelPosition: "right",
            size: "small",
          },
        },
        null,
        1
      );
    },
    // 确定导入json
    setJsonBtn() {
      try {
        this.initJson(this.jsonmsg);
        this.jsonDialog = false;
      } catch (err) {
        this.$message("导入的JSON格式有误");
      }
    },
    initJson(strJson) {
      // 写入 data json
      this.configFormData = JSON.parse(strJson);
      // 写入选中的组件json
      this.widgetFormSelect = this.configFormData.list[0];
    },
    showDialog() {},
    getBackData(item) {
      let raw = {
        argId:item.argId,
        argTitle: item.name,
        argType: item.tag,
        mustFill: item.options.required ? 1 : 0,
      };
      switch (item.tag) {
        case 1:
        case 2:
          raw.textDetail = {
            argPlaceholder: item.options.placeholder,
            maxLength: item.options.maxlength,
            minLength: item.options.minlength,
          };
          break;
        case 3:
        case 4:
        case 5:
        case 6:
          function format(arr) {
            const result = [];
            for (const item of arr) {
              if (item.children && item.children.length) {
                result.push({
                  optionName: item.label,
                  subOption: format(item.children),
                });
              } else {
                result.push({
                  optionName: item.label,
                });
              }
            }
            return result;
          }
          raw.checkDetail = format(item.options.valueData);
          break;
        case 7:
          raw.dateDetail = { ...dateMap[item.options.type] };
          break;
        case 8:
          raw.fileDetail = {
            psuffix: item.options.accept.join(","),
          };
          break;
        case 9:
          raw.fileDetail = {
            psuffix: item.options.accept.photo.join(","),
            vsuffix: item.options.accept.video.join(","),
            asuffix: item.options.accept.audio.join(","),
            dsuffix: item.options.accept.doc.join(","),
          };
          break;
        default:
          break;
      }
      return raw;
    },
    saveConfig() {
      if (!this.config.catalogueName) {
        this.$message.error("请输入模板名称");
        return;
      }
      // if (!this.config.remark) {
      //   this.$message.error("请输入备注");
      //   return;
      // }
      const args = [];
      const params = { ...this.config, args };
      for (const item of this.configFormData.list) {
        args.push(this.getBackData(item));
      }
      if (this.$id) {
        edit(this.$id, params).then((res) => {
          console.log(res);
          this.$message.success("编辑成功！");
        });
      } else {
        add(params).then((res) => {
          this.$id = res.catalogueId
          this.initData()
          this.$message.success("保存成功！");
        });
      }
    },
    preview() {
      const args = [];
      for (const item of this.configFormData.list) {
        args.push(this.getBackData(item));
      }
      this.previewData = { args };
      this.dialogVisible = true;
    },
  },
};
</script>
<style lang="scss" scoped>
.home {
  width: 100%;
  height: 100%;
}
.container-main {
  width: 100%;
  height: calc(100% - 48px);
}
.header-title {
  width: 100%;
  height: 50px !important;
  line-height: 50px !important;
  padding: 0px !important;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: bold;
}
.main-right {
  width: 300px !important;
  margin-right: 10px;
  background: #ffffff;
}
.main-left {
  width: 420px !important;
  margin-left: 10px;
  padding: 0 30px;
  background: #ffffff;
}
.box-padding {
  padding: 0px !important;
  position: relative;
  overflow-y: auto;
}
.widget-form-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.draggable-container {
  cursor: move;
  margin-top: 10px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  // grid-auto-rows: 25px;
  // gap: 17px;
  gap: 11px;
}
.main-bottom {
  border-bottom: 1px solid #999;
  height: 45px !important;
  line-height: 45px;
}
.header-padding {
  position: relative;
  padding: 0px !important;
  text-align: right;
}
.header-tags {
  margin-right: 10px;
  cursor: pointer;
}
.header-tags:nth-child(1) {
  position: absolute;
  left: 10px;
  top: 12px;
}
.divider {
  height: 10px;
  background-color: rgb(242, 242, 242);
  width: 100%;
}
.pd-10 {
  padding: 0 10px;
}
.c-tag {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 70px;
  border-radius: 4px;
  background: #f7f7f7;
  &__icon {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 32px;
    height: 32px;
  }
  &__name {
    flex: 0 0 30px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
.header {
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #ffffff;
  margin-bottom: 8px;
  border-radius: 6px;
  padding: 0 15px;
  position: sticky;
  top: 0;
  &__title {
    font-weight: 600;
    color: #2d2d2d;
  }
  &__btns {
    display: flex;
    ::v-deep{
    .el-button + .el-button{
    margin-left: 15px;
    }
    }
  }
}
</style>
